/**
 * Project: complex.java
 * 
 * File Created at 2010-5-27
 * $Id$
 * 
 * Copyright 2008 Alibaba.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Alibaba Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Alibaba.com.
 */
package complex.java.lang.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * @description:通用生成器
 * @author gaoliang
 * @date 2010-5-27
 * @version 1.0
 */
public class GenericGenerator {

    //
    @SuppressWarnings("unchecked")
    public static ProxyInterface generate() {
        try {
            // InvocationHandlerImpl 实现了 InvocationHandler 接口，并能实现方法调用从代理类到委托类的分派转发
            // 其内部通常包含指向委托类实例的引用，用于真正执行分派转发过来的方法调用
            //handler = Proxy.getInvocationHandler(new SpecificObject()); 可以不写InvocationHandlerImpl类
            InvocationHandler handler = new InvocationHanderImpl();
            
            // 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象
            Class proxyClass = Proxy.getProxyClass(ProxyInterface.class.getClassLoader(),
                    new Class[] { ProxyInterface.class });

            // 通过反射从生成的类对象获得构造函数对象
            //getConstructor 按参数类型,返回一个构造器
            Constructor constructor = proxyClass
                    .getConstructor(new Class[] { InvocationHandler.class });

            // 通过构造函数对象创建动态代理类实例
            ProxyInterface instance = (ProxyInterface) constructor
                    .newInstance(new Object[] { handler });

            //一步完成的写法(三合一)
            instance = (ProxyInterface) Proxy.newProxyInstance(ProxyInterface.class
                    .getClassLoader(), new Class[] { ProxyInterface.class }, handler);

            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
